问题
所谓位域是指利用就是用int枚举模式,将2的不同倍数赋予每个常量,这样就可以通过位操作将多个常量进行组合来表达具体的业务意义,比如下面的代码实例:
public class Text { public static final byte STYLE_BOLD = 1<<0; // 1 public static final byte STYLE_ITALIC = 1<<1; // 2 public static final byte STYLE_UNDERLINE = 1<<2; // 4 public static final byte STYLE_STRIKETHROUGH = 1<<3; // 6 //Parameter is bitwise OR of zero or more STYLE_ constants public void applyStyles(int styles) { ... } }
这段代码旨在通过位操作的方式将多种text风格进行组合。但是,很显然这是一种int枚举的方式,自然存在很多问题(见31条),应该使用什么样的类型数据能够替代位域?
解决
避免使用位域组合的方式的弊端,可以采用EnumSet类型数据。EnumSet支持从枚举类型中提取多个枚举常量进行组合的方式,并且这个类实现了Set接口,也具有类型安全性。使用EnumSet将上面的例子重写如下:
public class Text{ public enum Style{BOLD,ITALIC,UNDERLINE,STRIKETHROUGH} public void applyStyles(Set<Style> styles){ //实现方案 } } //客户端调用该方法为 text.applyStyles(EnumSet.of(Style.BOLD,Style.ITALIC));
结论
当需要将多个操作(或变量)进行组合时,可以使用EnumSet来代替使用int枚举进行位域操作的方式。EnumSet类集位域的简洁和性能的优势,以及枚举类型的所有优点与一身。实际上EnumSet也有个缺点,即它无法创建不可变的EnumSet(Java1.6为止没有解决)。同时,可以用Collections.unmodifiable将EnumSet封装起来,但是间接性和性能会受到影响。